<!-- 
  文件上传组件
  
  注：
    基于el-upload组件，没有分片上传等功能。
    请勿滥用，目前只是为了解决点击上传后，文件显示于qm-upload列表内的场景。

  用法：
    <qm-upload
      :dataKey="models.model[keyProp]"
      :categories="categories"
      :isShowUpload="isShowUpload"
      :uploadFiles="uploadFiles"
      @loaded="$parent.$emit('loaded')"
    ></qm-upload>

  说明：
    dataKey：业务主键，像userId这些，尽量指定
    categories：附件类型，和业务挂钩，取值参考：
      categories = ['身份证（正反面）', '医生诊断证明']
      
    isShowUpload：是否显示上传按钮，请根据业务来控制
    uploadFiles：上传成功的文件将会添加到这个数组里
    @loaded：loaded事件，组件的相关数据加载完之后会触发该事件，可用于数据加载时显示loading，加载完之后隐藏loading的场景
-->
<template>
  <el-table :data="tableData" border>
    <el-table-column type="index" width="50" label="序号"></el-table-column>
    <el-table-column prop="name" label="附件类型" width="200"></el-table-column>
    <el-table-column label="附件名称">
      <template slot-scope="scope">
        <el-table
          :data="scope.row.files"
          :show-header="false"
          style="width: 100%"
          v-loading="scope.row.tableLoading"
        >
          <el-table-column label="附件名称">
            <template slot-scope="scope2">
              <el-link
                type="primary"
                target="_blank"
                :href="getDownloadUrl(scope2.row.attachmentId)"
                title="点击下载"
                >{{ scope2.row.fileName }}</el-link
              >
            </template>
          </el-table-column>
          <el-table-column label="上传时间">
            <template slot-scope="scope2" width="150"
              >由{{ scope2.row.uploaderName }}上传于{{
                scope2.row.uploadTime
              }}</template
            >
          </el-table-column>
          <el-table-column label="操作" width="100">
            <template slot-scope="scope2">
              <el-button
                size="mini"
                type="danger"
                v-if="isShowUpload"
                @click="removeFile(scope2.row, scope.row, scope2.$index)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </template>
    </el-table-column>
    <el-table-column label="操作" width="100">
      <template slot-scope="scope" v-if="isShowUpload">
        <file-upload
          :bizType="scope.row.name"
          :fileType="scope.row.fileType"
          :fileSize="scope.row.fileSize"
          :dataKey="dataKey || 'qm-uploader-temp-data-key'"
          :ref="scope.row.uploaderRef"
          :fileList="scope.row.files"
        ></file-upload>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
import request from "@/utils/request";
import _ from "lodash";
import FileUpload from "./file-upload";

const DEFAULT_FILE_TYPE = "jpg,png,doc,docx,xls,xlsx,pdf,txt,zip,rar";
const DEFAULT_ATTACHMENT_TYPE = "attach";

export default {
  name: "qm-upload",
  components: {
    FileUpload,
  },
  props: {
    dataKey: {
      type: String,
      default: "qm-upload-temp-data-key",
    },
    isShowUpload: Boolean,
    categories: {
      type: Array,
      default: () => [],
    },
    uploadFiles: {
      type: Array,
      default: () => [],
    },
    attachmentType: {
      type: String,
      default: DEFAULT_ATTACHMENT_TYPE,
    },
    /**
     * 默认取后台配置(先取数据字典、再取AttachmentType)，如果设置了fileType，则取当前的fileType.
     * 如果都没设置，则取 DEFAULT_FILE_TYPE.
     */
    fileType: {
      type: String,
      default: undefined,
    },
    fileStatusText: {
      type: Object,
    },
  },
  data() {
    return {
      tableData: [],
      attachmentList: [],
      attachmentTypes: [],
    };
  },
  computed: {},
  methods: {
    uploadSuccess(attachment) {
      this.uploadFiles.push(attachment);
    },
    removeFile: function (file, row, $index) {
      this.$confirm("确定删除： " + file.fileName + "？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          row.tableLoading = true;
          request({
            url: "/attachment/remove",
            method: "post",
            data: { attachmentId: file.attachmentId },
          })
            .then((r) => {
              if (r && r.success) {
                row.files.splice($index, 1);
                let idx = _.findIndex(this.uploadFiles, (item) => {
                  return item.attachmentId === file.attachmentId;
                });
                if (idx !== -1) {
                  this.uploadFiles.splice(idx, 1);
                }
                row.tableLoading = false;
              } else {
                this.msgError((r || {}).message || "删除失败");
                row.tableLoading = false;
              }
            })
            .catch((e) => {
              row.tableLoading = false;
            });
        })
        .catch(() => {});
    },
    getDownloadUrl(attachmentId) {
      return `${process.env.VUE_APP_BASE_API}/attachment/download?attachmentId=${attachmentId}`;
    },

    loadData() {
      (this.attachmentList || []).forEach((f, idx) => {
        this.tableData.push({
          ...f,
          uploaderVisible: false,
          uploaderRef: `qm-upload-${idx}`,
          tableLoading: false,
        });
      });
      return new Promise((rs, rj) => {
        let datakey = this.dataKey;
        if (!datakey) {
          rs();
          return;
        }
        request({
          url: "/attachment/getAllByDataKey",
          method: "get",
          params: { dataKey: datakey },
        }).then((files) => {
          if (files) {
            this.tableData.forEach((row) => {
              row.files = [];
              files
                .filter((f) => {
                  return f.bizType == row.name;
                })
                .forEach((f) => {
                  row.files.push(f);
                });
            });
          }
          rs();
        });
      });
    },
    addCategory(bizType, attachmentType, limit, uploadUri) {
      let find =
        _.find(this.attachmentTypes || [], (item) => {
          return item.type === attachmentType;
        }) || {};
      this.attachmentList.push({
        name: bizType,
        type: find.type || DEFAULT_ATTACHMENT_TYPE,
        fileType: this.fileType || find.fileType || DEFAULT_FILE_TYPE,
        fileSize: parseInt(find.fileSize || 20),
        limit: limit,
        uploadWindow: uploadUri || "/attachment/upload",
        files: [],
      });
    },
    async fetchAttachmentTypeData() {
      await request({
        url: "/attachment/getAllAttachmentTypes",
        method: "post",
        data: {},
      }).then((r) => {
        this.attachmentTypes = r;
      });
    },

    fetchData() {
      return new Promise((rs, rj) => {
        this.fetchAttachmentTypeData().then((r) => {
          this.categories.forEach((c) => {
            this.addCategory(c, this.attachmentType);
          });
          this.loadData().then((r) => {
            rs();
          });
        });
      });
    },
  },

  created() {
    this.fetchData().then((r) => {
      this.$emit("loaded");
    });
  },
};
</script>

<style scoped></style>
